#include "CenterBattleLogManager.h"
#include "CenterBattleManager.h"
#include "StringConverter.h"
#include "ResourceManager.h"
#include "Database/DatabaseEnv.h"
#include "StringConverter.h"
#include "json/json.h"
#include "NGLog.h"
#include "Character.h"
#include "CharManager.h"
#include "Items.h"
#include "ItemManager.h"
#include "Users.h"
#include "UserManager.h"
#include "Channels.h"
#include "ChannelManager.h"
#include "ItemModelManager.h"
#include "Message.h"
#include "CenterBankManager.h"
#include "VipCardManager.h"
#include "Tools.h"
#include "XMLData.h"
#include "GameDefine.h"
#include XMLDATA_MGR_PATH
#include LOGIC_MGR_PATH
#include LOG_MGR_PATH
#include PROTOCOLS_MGR_PATH
#include "OpcodesEx.h"
#include "WorldPacket.h"
#include "AIInterface.h"
#include "url.h"
#include "CRUsersManager.h"
#include "CenterClubManager.h"

CenterBattleLogManager::CenterBattleLogManager()
{
	m_mapClubBattleHistory.clear();
}

//=============================好友记录信息相关===================================
bool CenterBattleLogManager::AddCenterBattleLog(CenterBattleLog & cb)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fields);
	
	fields["group_id"] = 1;
	fields["status"] = cb.status;
	fields["type"] = cb.type;
	fields["sub_type"] = cb.sub_type;
	fields["cb_id"] = cb.cb_id;
	fields["gz_id"] = cb.gz_id;
	fields["game_id"] = cb.game_id;
	fields["club_id"] = cb.club_id;
	fields["club_room_id"] = cb.club_room_id;
	fields["src_pid"] = cb.src_pid;
	
	fields["user_openid"] = cb.user_openid;
	fields["user_nick"] = cb.user_nick;
	fields["user_ip"] = cb.user_ip;
	fields["user_addr"] = cb.user_addr;
	
	fields["data1"] = cb.data1;
	fields["data2"] = cb.data2;
	fields["data3"] = cb.data3;
	fields["data4"] = cb.data4;
	fields["data5"] = cb.data5;
	fields["data6"] = cb.data6;
	fields["data7"] = cb.data7;
	fields["data8"] = cb.data8;
	
	fields["data9"] = cb.data9;
	fields["data10"] = cb.data10;
	fields["data11"] = cb.data11;
	fields["data12"] = cb.data12;
	
	fields["fdata1"] = cb.fdata1;
	fields["fdata2"] = cb.fdata2;
	fields["fdata3"] = cb.fdata3;
	fields["fdata4"] = cb.fdata4;
	
	fields["sdata1"] = cb.sdata1;
	fields["sdata2"] = cb.sdata2;
	fields["sdata3"] = cb.sdata3;
	fields["sdata4"] = cb.sdata4;
	fields["sdata5"] = cb.sdata5;
	fields["sdata6"] = cb.sdata6;
	fields["sdata7"] = cb.sdata7;
	fields["sdata8"] = cb.sdata8;
	
	fields["info"] = cb.info;
	fields["record_data"] = cb.record_data;
	fields["create_time"] = cb.create_time;
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fields))
	{
		Log.Debug("CenterBattleLogManager::AddCenterBattleLog","添加数据失败！");
		return false;
	}
		
	
	cb.battle_log_id = fields["battle_log_id"].GetUInt32();
	return true;
}


bool CenterBattleLogManager::UpdateCenterBattleLog(const CenterBattleLog & cb)
{
	Fields fields;
	
	fields["status"] = cb.status;
	
	fields["data1"] = cb.data1;
	fields["data2"] = cb.data2;
	fields["data3"] = cb.data3;
	fields["data4"] = cb.data4;
	fields["data5"] = cb.data5;
	fields["data6"] = cb.data6;
	fields["data7"] = cb.data7;
	fields["data8"] = cb.data8;
	
	fields["data9"] = cb.data9;
	fields["data10"] = cb.data10;
	fields["data11"] = cb.data11;
	fields["data12"] = cb.data12;
	
	fields["fdata1"] = cb.fdata1;
	fields["fdata2"] = cb.fdata2;
	fields["fdata3"] = cb.fdata3;
	fields["fdata4"] = cb.fdata4;
	
	fields["sdata5"] = cb.sdata5;
	fields["sdata6"] = cb.sdata6;
	fields["sdata7"] = cb.sdata7;
	fields["sdata8"] = cb.sdata8;
	
	fields["info"] = cb.info;
	fields["record_data"] = cb.record_data;
	fields["create_time"] = cb.create_time;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fields, "`battle_log_id` = %u", cb.battle_log_id);
	return count > 0;
}

#define SQLBUFER_LEN 16384

bool CenterBattleLogManager::UpdateCenterBattleLog(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, fields, sql);
	return count > 0;
}

bool CenterBattleLogManager::UpdateCenterBattleLog(const uint32 &cb_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, fields, "`battle_log_id` = %u", cb_id);
	return count > 0;
}


bool CenterBattleLogManager::GetCenterBattleLog(const uint32 &cbl_id, CenterBattleLog * cb)
{
	assert (cb);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &rows, "`battle_log_id` = %u", cbl_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	cb->battle_log_id = fields["battle_log_id"].GetUInt32();
	cb->group_id = fields["group_id"].GetUInt32();
	cb->status = fields["status"].GetUInt32();
	cb->type = fields["type"].GetUInt32();
	cb->sub_type = fields["sub_type"].GetUInt32();
	cb->cb_id = fields["cb_id"].GetUInt32();
	cb->gz_id = fields["gz_id"].GetUInt32();
	cb->game_id = fields["game_id"].GetUInt32();
	cb->club_id = fields["club_id"].GetUInt64();
	cb->club_room_id = fields["club_room_id"].GetUInt64();
	
	cb->src_pid = fields["src_pid"].GetUInt32();
	cb->user_openid = fields["user_openid"].GetValue();
	cb->user_nick = fields["user_nick"].GetValue();
	cb->user_ip = fields["user_ip"].GetValue();
	cb->user_addr = fields["user_addr"].GetValue();
	
	cb->data1 = fields["data1"].GetUInt32();
	cb->data2 = fields["data2"].GetUInt32();
	cb->data3 = fields["data3"].GetUInt32();
	cb->data4 = fields["data4"].GetUInt32();
	cb->data5 = fields["data5"].GetUInt32();
	cb->data6 = fields["data6"].GetUInt32();
	cb->data7 = fields["data7"].GetUInt32();
	cb->data8 = fields["data8"].GetUInt32();
	
	cb->data9 = fields["data9"].GetInt32();
	cb->data10 = fields["data10"].GetInt32();
	cb->data11 = fields["data11"].GetInt32();
	cb->data12 = fields["data12"].GetInt32();
	
	cb->fdata1 = fields["fdata1"].GetFloat();
	cb->fdata2 = fields["fdata2"].GetFloat();
	cb->fdata3 = fields["fdata3"].GetFloat();
	cb->fdata4 = fields["fdata4"].GetFloat();
	
	cb->sdata1 = fields["sdata1"].GetValue();
	cb->sdata2 = fields["sdata2"].GetValue();
	cb->sdata3 = fields["sdata3"].GetValue();
	cb->sdata4 = fields["sdata4"].GetValue();
	cb->sdata5 = fields["sdata5"].GetValue();
	cb->sdata6 = fields["sdata6"].GetValue();
	cb->sdata7 = fields["sdata7"].GetValue();
	cb->sdata8 = fields["sdata8"].GetValue();
	
	cb->info = fields["info"].GetValue();
	cb->record_data = fields["record_data"].GetValue();
	cb->create_time = fields["create_time"].GetValue();
	
	cb->update_key = fields["update_key"].GetUInt32();
	return true;
}


uint32 CenterBattleLogManager::GetCenterBattleLogList(std::list<CenterBattleLog> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		CenterBattleLog cb;
		Fields &fields = *iter;
		
		cb.battle_log_id = fields["battle_log_id"].GetUInt32();
		cb.group_id = fields["group_id"].GetUInt32();
		cb.status = fields["status"].GetUInt32();
		cb.type = fields["type"].GetUInt32();
		cb.sub_type = fields["sub_type"].GetUInt32();
		cb.cb_id = fields["cb_id"].GetUInt32();
		cb.gz_id = fields["gz_id"].GetUInt32();
		cb.game_id = fields["game_id"].GetUInt32();
		cb.club_id = fields["club_id"].GetUInt64();
		cb.club_room_id = fields["club_room_id"].GetUInt64();
		
		cb.src_pid = fields["src_pid"].GetUInt32();
		cb.user_openid = fields["user_openid"].GetValue();
		cb.user_nick = fields["user_nick"].GetValue();
		cb.user_ip = fields["user_ip"].GetValue();
		cb.user_addr = fields["user_addr"].GetValue();
		
		cb.data1 = fields["data1"].GetUInt32();
		cb.data2 = fields["data2"].GetUInt32();
		cb.data3 = fields["data3"].GetUInt32();
		cb.data4 = fields["data4"].GetUInt32();
		cb.data5 = fields["data5"].GetUInt32();
		cb.data6 = fields["data6"].GetUInt32();
		cb.data7 = fields["data7"].GetUInt32();
		cb.data8 = fields["data8"].GetUInt32();
		
		cb.data9 = fields["data9"].GetInt32();
		cb.data10 = fields["data10"].GetInt32();
		cb.data11 = fields["data11"].GetInt32();
		cb.data12 = fields["data12"].GetInt32();
		
		cb.fdata1 = fields["fdata1"].GetFloat();
		cb.fdata2 = fields["fdata2"].GetFloat();
		cb.fdata3 = fields["fdata3"].GetFloat();
		cb.fdata4 = fields["fdata4"].GetFloat();
		
		cb.sdata1 = fields["sdata1"].GetValue();
		cb.sdata2 = fields["sdata2"].GetValue();
		cb.sdata3 = fields["sdata3"].GetValue();
		cb.sdata4 = fields["sdata4"].GetValue();
		cb.sdata5 = fields["sdata5"].GetValue();
		cb.sdata6 = fields["sdata6"].GetValue();
		cb.sdata7 = fields["sdata7"].GetValue();
		cb.sdata8 = fields["sdata8"].GetValue();
		
		cb.info = fields["info"].GetValue();
		cb.record_data = fields["record_data"].GetValue();
		cb.create_time = fields["create_time"].GetValue();
		cb.update_key = fields["update_key"].GetUInt32();
		lstData->push_back(cb);
	}
	
	return lstData->size();
}

//===========================逻辑操作相关=============================

// 提交玩家组局游戏日志cb_id 组局ID
bool CenterBattleLogManager::CommitCenterBattleLog(CharPtr & pChr, const uint32 & cb_id, Fields & fields)
{
	if(pChr.isNull() || !cb_id)
		return false;

WGS_CENTERBATTLELOG_LOCK
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	// 先找是否已经存在记录
	std::list<CenterBattleLog> lstData;
	GetCenterBattleLogList(&lstData, "status < 255 and `cb_id` = %u and `user_pid` = %u", cb_id, pUser->getUInt32Field("userid"));
	
	if(lstData.size())
	{// 更新数据
		
		CenterBattleLog cb = *lstData.begin();
		// 修改数据（需要考虑数据是修改还是增加）
		
		cb.data1 = fields["data1"].GetUInt32();
		cb.data2 = fields["data2"].GetUInt32();
		cb.data3 = fields["data3"].GetUInt32();
		cb.data4 = fields["data4"].GetUInt32();
		cb.data5 = fields["data5"].GetUInt32();
		cb.data6 = fields["data6"].GetUInt32();
		cb.data7 = fields["data7"].GetUInt32();
		cb.data8 = fields["data8"].GetUInt32();
		
		cb.data9 = fields["data9"].GetInt32();
		cb.data10 = fields["data10"].GetInt32();
		cb.data11 = fields["data11"].GetInt32();
		cb.data12 = fields["data12"].GetInt32();
		
		cb.fdata1 = fields["fdata1"].GetFloat();
		cb.fdata2 = fields["fdata2"].GetFloat();
		cb.fdata3 = fields["fdata3"].GetFloat();
		cb.fdata4 = fields["fdata4"].GetFloat();
		
		cb.sdata1 = fields["sdata1"].GetValue();
		cb.sdata2 = fields["sdata2"].GetValue();
		cb.sdata3 = fields["sdata3"].GetValue();
		cb.sdata4 = fields["sdata4"].GetValue();
		cb.sdata5 = fields["sdata5"].GetValue();
		cb.sdata6 = fields["sdata6"].GetValue();
		cb.sdata7 = fields["sdata7"].GetValue();
		cb.sdata8 = fields["sdata8"].GetValue();
		
		cb.info = fields["info"].GetValue();
		cb.record_data = fields["record_data"].GetValue();
		cb.create_time = fields["create_time"].GetValue();
		cb.update_key = fields["update_key"].GetUInt32();
		
		UpdateCenterBattleLog(cb_id, &fields);
	}
	else
	{// 添加数据
		
		CenterBattleLog cb;
		
		cb.status = 1;											//状态
		cb.type = fields["type"].GetUInt32();					//日志类型
		cb.sub_type = fields["sub_type"].GetUInt32();			//日志子类型
		cb.cb_id = fields["cb_id"].GetUInt32();					//组局ID
		cb.gz_id = fields["gz_id"].GetUInt32();					//要创建牌桌的分区ID
		cb.game_id = fields["game_id"].GetUInt32();				//游戏ID
		cb.club_id = fields["club_id"].GetUInt64();				//俱乐部ID
		cb.club_room_id = fields["club_room_id"].GetUInt64();	//俱乐部房间ID
		
		cb.src_pid = pUser->getUInt32Field("platform_id");		//日志所属玩家PID
		cb.user_openid = pUser->getStringField("sdata1");		//玩家openid
		cb.user_nick = pUser->getStringField("nick");			//玩家昵称
		cb.user_ip = pUser->getStringField("ip");				//玩家IP
		cb.user_addr = pUser->getStringField("addr");			//玩家地址
		
		cb.data1 = fields["data1"].GetUInt32();
		cb.data2 = fields["data2"].GetUInt32();
		cb.data3 = fields["data3"].GetUInt32();
		cb.data4 = fields["data4"].GetUInt32();
		cb.data5 = fields["data5"].GetUInt32();
		cb.data6 = fields["data6"].GetUInt32();
		cb.data7 = fields["data7"].GetUInt32();
		cb.data8 = fields["data8"].GetUInt32();
		
		cb.data9 = fields["data9"].GetInt32();
		cb.data10 = fields["data10"].GetInt32();
		cb.data11 = fields["data11"].GetInt32();
		cb.data12 = fields["data12"].GetInt32();
		
		cb.fdata1 = fields["fdata1"].GetFloat();
		cb.fdata2 = fields["fdata2"].GetFloat();
		cb.fdata3 = fields["fdata3"].GetFloat();
		cb.fdata4 = fields["fdata4"].GetFloat();
		
		cb.sdata1 = fields["sdata1"].GetValue();
		cb.sdata2 = fields["sdata2"].GetValue();
		cb.sdata3 = fields["sdata3"].GetValue();
		cb.sdata4 = fields["sdata4"].GetValue();
		cb.sdata5 = fields["sdata5"].GetValue();
		cb.sdata6 = fields["sdata6"].GetValue();
		cb.sdata7 = fields["sdata7"].GetValue();
		cb.sdata8 = fields["sdata8"].GetValue();
		
		cb.info = fields["info"].GetValue();
		cb.record_data = fields["record_data"].GetValue();
		cb.create_time = fields["create_time"].GetValue();
		cb.update_key = fields["update_key"].GetUInt32();
		
		AddCenterBattleLog(cb);
	}
	
	return true;
}

// 增加组局游戏记录
bool CenterBattleLogManager::AddCenterBattleRecordLog(BattleTotalLog btLog, uint8 pos)
{
	if (btLog.cm_id == 0)
	{
		// 添加每轮输赢记录
		AddCenterBattleLoopWinLoseLog(btLog, pos);
		// 添加完整组局记录（有则更新）
		AddCenterBattleLoopTotalLog(btLog);
	}

	Log.Debug("CenterBattleLogManager::AddCenterBattleRecordLog", "club_id[%u] club_room_id[%u] cm_id[%d]", btLog.club_id, btLog.club_room_id, btLog.cm_id);
	if (btLog.club_id || btLog.club_room_id)
	{
		AddCenterClubRoomBattleLog(btLog);
	}
	else if (btLog.cm_id != 0)
	{
		// 添加每轮输赢记录
		AddCenterMatchLoopWinLoseLog(btLog, pos);
		// 添加完整组局记录（有则更新）
		AddCenterMatchLoopTotalLog(btLog);
	}

	return true;
}

// 玩家每轮输赢记录，一桌结算了，给每个玩家进行日志记录
bool CenterBattleLogManager::AddCenterBattleLoopWinLoseLog(BattleTotalLog logInfo, uint8 pos)
{
WGS_CENTERBATTLELOG_LOCK
	CenterBattleLog cb;
	CenterBattle cb_info;
	sCenterBattleMgr.GetCenterBattle(logInfo.cb_id, &cb_info);
	
	if(logInfo.cb_id)
	{
		cb.cb_id = cb_info.cb_id;
		cb.gz_id = cb_info.gz_id;
		cb.game_id = cb_info.game_id;
		cb.club_id = cb_info.club_id;
		cb.club_room_id = cb_info.club_room_id;
		
		cb.data1 = cb_info.base_coins;	// 底分
		cb.data2 = cb_info.fan_coins;	// 翻分
		cb.data5 = cb_info.pid;			// 房主PID
		cb.data7 = cb_info.limit_loop;	// 总局数
	}
	else
	{
		cb.cb_id = logInfo.cb_id;
		cb.gz_id = logInfo.gz_id;
		cb.game_id = logInfo.game_id;
		cb.club_id = logInfo.club_id;
		cb.club_room_id = logInfo.club_room_id;
		
		cb.data1 = logInfo.base_coins;	// 底分
		cb.data2 = logInfo.fan_coins;	// 翻分
		cb.data5 = logInfo.owner_pid;	// 房主PID
		cb.data8 = logInfo.channel_id;	// 牌局ID
	}
	
	cb.type = enCenterBattleLogType_PlayerWinLose;			// 日志类型-每轮详细输赢
	
	cb.data3 = logInfo.loop_id;		// 轮次ID
	cb.data4 = logInfo.use_time;	// 使用时间
	cb.data6 = logInfo.bHaveVedio;	// 是否拥有录像
	cb.data12 = logInfo.mode;		// 游戏玩法
	cb.data10 = logInfo.zone_id;	// 赛区ID
	
	if(logInfo.agent_id)
		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(logInfo.agent_id, logInfo.game_id, logInfo.mode);
	else
		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(cb_info.reg_from, cb_info.game_id, cb_info.mode);	// 游戏名
	
	cb.sdata2 = cb_info.battle_name;
	cb.sdata3 = cb_info.name;
	cb.sdata4 = cb_info.head;
	
	Json::Reader reader;
	Json::FastWriter w;
	Json::Value val, valPay;
	
	std::vector<CenterBattlePlayerWinLose>::iterator iter,ei = logInfo.player_winLose.end();
	for(iter = logInfo.player_winLose.begin(); iter!=ei; ++iter)
	{
		String strPid = StringConverter::toString((*iter).platform_id);
		uint32 pid = (*iter).platform_id;
		
		val["players"][strPid]["pid"] = pid;										// PID
		val["players"][strPid]["name"] = string_url_encode((*iter).player_nick); 	// 昵称
		val["players"][strPid]["desc"] = string_url_encode((*iter).player_desc);	// 头像
		val["players"][strPid]["winlose"] = (*iter).winLoseScore;					// 输赢积分
		val["players"][strPid]["json_data"] = (*iter).json_data;					// 详细输赢
		
		// 更新玩家总输赢积分 cr_users.total_winlose_score
		CRUser cru;
		if(sCRUsersMgr.GetCRUser(pid, &cru))
		{
			Fields fields;
			fields["total_winlose_score"] = cru.total_winlose_score + (*iter).winLoseScore;
			sCRUsersMgr.UpdateCRUser(pid, &fields);
		}
		
		//============纯json版=======================
		// Json::Value val2;
		// reader.parse((*iter).json_data, val2);
		// val["players"][strPid]["json_data"] = val2;							// 详细输赢
		
		val["players"][strPid]["pos"] = pos;								// 玩家位置
		pos++;
	}
	
	if(cb_info.pay_mode == enPayMode_AAPay)
	{// AA制付费，判断开始游戏的玩家是否付费
		
		reader.parse(cb_info.sdata4, valPay);	// 付费玩家
		bool bAddNewChar = false;
		
		if(valPay.size())
		{// 有付费玩家
			std::map<uint32, uint32> mapPayChars;
			for(iter = logInfo.player_winLose.begin(); iter!=ei; ++iter)
			{
				bool bFindChar = false;
				uint32 char_id = (*iter).char_id;
				for(Json::Value::iterator iterVal=valPay.begin(); iterVal!=valPay.end(); ++iterVal)
				{
					if(char_id == (*iterVal)["cid"].asUInt())
					{
						bFindChar = true;
						break;
					}
				}
				
				if(!bFindChar)
				{
					bAddNewChar = true;
					mapPayChars.insert(std::make_pair((*iter).platform_id, (*iter).char_id));
				}
			}
			
			uint8 index = valPay.size();
			std::map<uint32, uint32>::iterator itMp, eiMp = mapPayChars.end();
			for(itMp = mapPayChars.begin(); itMp!=eiMp; ++itMp)
			{
				uint32 char_id = itMp->second;
				CharPtr pChr = sCharMgr.load(char_id);
				if(pChr.isNull())
					continue;
				
				sGLMgr.reduceItemNum(pChr, cb_info.data1, cb_info.data2);
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_CenterBattle, cb_info.data1, en_UNT_Reduce, cb_info.data2, cb_info.cb_id);
				
				Json::Value valPlayer;
				valPlayer["pid"] = itMp->second;
				valPlayer["cid"] = char_id;
				valPlayer["gz_id"] = uint32(pChr->getUInt32Field("gz_id"));
				valPlayer["model_id"] = cb_info.data1;
				valPlayer["num"] = cb_info.data2;
				
				uint32 takein_coins = sCenterClubMemberMgr.GetMemberTakeinCoins(cb_info.club_id, (*iter).platform_id);
				if(takein_coins)
					valPlayer["takein_coins"] = takein_coins;
				
				valPay[index++] = valPlayer;
			}
		}
		else
		{
			if(cb_info.data1 > 0)
			{// 需要付费
				bAddNewChar = true;
				uint8 index = 0;
				for(iter = logInfo.player_winLose.begin(); iter!=ei; ++iter)
				{
					uint32 char_id = (*iter).char_id;
					CharPtr pChr = sCharMgr.load(char_id);
					if(pChr.isNull())
						continue;
					
					sGLMgr.reduceItemNum(pChr, cb_info.data1, cb_info.data2);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_CenterBattle, cb_info.data1, en_UNT_Reduce, cb_info.data2, cb_info.cb_id);
					
					Json::Value valPlayer;
					valPlayer["pid"] = (*iter).platform_id;
					valPlayer["cid"] = (*iter).char_id;
					valPlayer["gz_id"] = uint32(pChr->getUInt32Field("gz_id"));
					valPlayer["model_id"] = cb_info.data1;
					valPlayer["num"] = cb_info.data2;
					
					uint32 takein_coins = sCenterClubMemberMgr.GetMemberTakeinCoins(cb_info.club_id, (*iter).platform_id);
					if(takein_coins)
						valPlayer["takein_coins"] = takein_coins;
					
					valPay[index++] = valPlayer;
				}
			}
		}
		
		if(bAddNewChar)
		{// 有新的付费玩家，加入数据统计，更新组局数据
			cb_info.sdata4 = w.write(valPay);
			sCenterBattleMgr.UpdateCenterBattle(cb_info);
		}
	}
	
	val["data"] = logInfo.extra_data;			// 游戏输赢明细
	
	//===============纯json版=====================
	// Json::Value val3;
	// reader.parse(logInfo.extra_data, val3);	
	// val["data"] = val3;						// 游戏输赢明细						
	
	cb.sdata5 = w.write(val);					// 输赢详细
	
	cb.create_time = sGLMgr.GetCurDateTime();	// 结束时间
	cb.record_data = logInfo.record_data;		// 游戏流程记录
	
	bool bFzPlay = false;
	for(iter = logInfo.player_winLose.begin(); iter!=ei; ++iter)
	{// 房主在游戏
		if((*iter).platform_id == cb_info.pid)
			bFzPlay = true;
		
		cb.data9 = (*iter).winLoseScore;
		cb.src_pid = (*iter).platform_id;
		cb.user_nick = (*iter).player_nick;
		AddCenterBattleLog(cb);
	}
	
	stCenterBattleOpenCoins stCOC = sXmlDataMgr.GetCenterBattleOpenCoins(cb_info.reg_from, cb_info.game_id, cb_info.limit_loop, enCenterBattleLimitType_Loop, cb_info.mode);
	if(!bFzPlay && !stCOC.nCloseOwnerRecord)
	{// 给房主加上日志
		cb.data9 = 0;
		cb.src_pid = cb_info.pid;
		cb.user_nick = cb_info.name;
		AddCenterBattleLog(cb);
	}
	
	return true;
}

// 组局整体记录（完成）
bool CenterBattleLogManager::AddCenterBattleLoopTotalLog(BattleTotalLog totalLog)
{
WGS_CENTERBATTLELOG_LOCK
	CenterBattleLog cb;
	CenterBattle cb_info;
	sCenterBattleMgr.GetCenterBattle(totalLog.cb_id, &cb_info);
	
	if(cb_info.data3)
	{// 可中途加入的才改变游戏状态
		sCenterBattleMgr.SetCentetBattleProcess(totalLog.cb_id);
	}
	
	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "cb_id = %u and type = %u", totalLog.cb_id, enCenterBattleLogType_BattleTotalInfo);
	
	bool bFind = logs.size();
	if(logs.size())
		cb = *logs.begin();
	
	if(bFind)
	{// 更新数据
		cb.data4++;							// 总轮数增加
		cb.data4 = cb_info.curr_loop;		// 当前局数
		cb.data8 = time(0) - cb.data3;		// 游戏最终用时（每一把 结算）
	}
	else
	{// 创建数据
		cb.cb_id = totalLog.cb_id;
		cb.gz_id = cb_info.gz_id;			// 分区ID
		cb.game_id = cb_info.game_id;		// 游戏ID
		cb.club_id = cb_info.club_id;		// 俱乐部ID
		cb.club_room_id = cb_info.club_room_id;		// 俱乐部房间ID
		
		cb.src_pid = cb_info.pid;			// 房主PID
		
		cb.type = enCenterBattleLogType_BattleTotalInfo;			// 一局日志
		
		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(cb_info.reg_from, cb_info.game_id, cb_info.mode);	// 游戏名
		cb.sdata2 = cb_info.sdata2;			// 玩法
		cb.sdata3 = cb_info.name;			// 房主名
		cb.sdata4 = cb_info.head;			// 房主头像
		cb.sdata7 = cb_info.join_code;		// 进入验证码
		
		cb.data1 = cb_info.base_coins;		// 底分
		cb.data2 = cb_info.fan_coins;		// 翻分
		cb.data3 = totalLog.use_time;		// 游戏创建时间
		cb.data4 = cb_info.curr_loop;		// 当前局数
		cb.data5 = cb_info.limit_loop;		// 总局数
		cb.data8 = time(0) - cb.data3;		// 游戏最终用时
		
		cb.data11 = cb_info.top_times;		// 封顶倍数
		cb.data12 = totalLog.mode;			// 游戏玩法
		
		cb.create_time = totalLog.create_time;	// 创建时间
	}
	
	Json::Reader reader;
	Json::FastWriter w;
	Json::Value val_player,val_maxInfo, valData2;
	reader.parse(cb.sdata5, val_player);			// 玩家一局中输赢json
	reader.parse(totalLog.extra_data2, valData2);	// 牌局附加数据2（存放庄家，用时等，游戏比较特殊的信息）
	
	valData2["game_time"] = cb.data8;				// 游戏用时
	totalLog.extra_data2 = w.write(valData2);		// 牌桌附加数据2
	
	sCenterBattleMgr.UpdatePlayersInfo(totalLog.cb_id, totalLog.player_winLose, totalLog.extra_data2);
	
	// 赢最多，输最多
	int max_winScore = 0;
	int max_loseScore = 0;
	
	uint32 max_winPid = 0;
	uint32 max_losePid = 0;
	
	std::map<uint32, int32> mapPlayerWinLose;
	for (Json::Value::iterator iterVal=val_player.begin(); iterVal!=val_player.end(); ++iterVal)
	{
		mapPlayerWinLose.insert(std::make_pair((*iterVal)["pid"].asUInt(), (*iterVal)["winlose"].asInt()));
	}
	
	std::vector<CenterBattlePlayerWinLose>::iterator iter,ei = totalLog.player_winLose.end();
	for(iter = totalLog.player_winLose.begin(); iter!=ei; ++iter)
	{
		if((*iter).winLoseScore > 0)
		{// 赢家
			// 总赢
			cb.data6 += (*iter).winLoseScore;
			// 最大赢钱
			if(cb.data7 < uint32((*iter).winLoseScore))
				cb.data7 = (*iter).winLoseScore;
			
			if(cb.data9 < (*iter).winLoseScore)
			{// 本局最大赢钱
				cb.data9 = (*iter).winLoseScore;
			}
			
			// 总赢钱
			cb.data10 += (*iter).winLoseScore;
		}
		
		bool bFindChar = false;
		for (Json::Value::iterator iterVal=val_player.begin(); iterVal!=val_player.end(); ++iterVal)
		{
			if((*iter).platform_id == (*iterVal)["pid"].asUInt())
			{
				bFindChar = true;
				// (*iterVal)["player_status"] = enCenterBattlePlayerStatus_Free;		// 现在模式不需要修改玩家状态
				(*iterVal)["winlose"] = (*iterVal)["winlose"].asInt() + (*iter).winLoseScore;
				
				Json::Value valEx;
				Json::Reader reader;
				reader.parse((*iter).json_data, valEx);
				
				if(valEx.isMember("banker_loop"))
				{// 有局数直接赋值
					(*iterVal)["player_count"] = valEx["banker_loop"].asUInt();
				}
				else
				{// 没有局数，就累加
					(*iterVal)["player_count"] = (*iterVal)["player_count"].asUInt() + 1;
				}
				
				(*iterVal)["json_data"] = (*iter).json_data;							// 详细输赢
				
				std::map<uint32, int32>::iterator fit = mapPlayerWinLose.find((*iterVal)["pid"].asUInt());
				if(fit == mapPlayerWinLose.end())
					mapPlayerWinLose.insert(std::make_pair((*iterVal)["pid"].asUInt(), (*iterVal)["winlose"].asInt()));
				else
					fit->second = (*iterVal)["winlose"].asInt();
				
				break;
			}
		}
		
		char str[256] = "";
		sprintf(str, "%u", (*iter).platform_id);
		
		if(!bFindChar)
		{
			val_player[str]["pid"] = (*iter).platform_id;			// PID
			val_player[str]["cid"] = (*iter).char_id;				// CID
			val_player[str]["name"] = string_url_encode((*iter).player_nick); 			// 昵称
			val_player[str]["desc"] = string_url_encode((*iter).player_desc);			// 头像
			val_player[str]["winlose"] = (*iter).winLoseScore;		// 输赢积分
			val_player[str]["player_count"] = 1;					// 总游戏局属
			val_player[str]["player_status"] = enCenterBattlePlayerStatus_Free;			// 角色状态（空闲 游戏中 离开）
			val_player[str]["json_data"] = (*iter).json_data;							// 详细输赢
			uint32 takein_coins = sCenterClubMemberMgr.GetMemberTakeinCoins(cb_info.club_id, (*iter).platform_id);
			if(takein_coins)
				val_player[str]["takein_coins"] = takein_coins;
			
			std::map<uint32, int32>::iterator fit = mapPlayerWinLose.find((*iter).platform_id);
			if(fit == mapPlayerWinLose.end())
				mapPlayerWinLose.insert(std::make_pair((*iter).platform_id, (*iter).winLoseScore));
			else
				fit->second = (*iter).winLoseScore;
		}
	}
	
	std::map<uint32, int32>::iterator itWL, eiWL = mapPlayerWinLose.end();
	for(itWL = mapPlayerWinLose.begin(); itWL!=eiWL; ++itWL)
	{
		if(itWL->second > 0)
		{
			if(max_winScore < itWL->second)
			{// 赢最多
				max_winScore = itWL->second;
				max_winPid = itWL->first;
			}
		}
		else if(itWL->second < 0)
		{
			if(max_loseScore > itWL->second)
			{// 输最多
				max_loseScore = itWL->second;
				max_losePid = itWL->first;
			}
		}
	}
	
	val_maxInfo["win_max"]["pid"] = max_winPid;
	val_maxInfo["lose_max"]["pid"] = max_losePid;
	
	cb.sdata5 = w.write(val_player);							// 一局中总输赢
	cb.sdata6 = w.write(val_maxInfo);							// 最佳数据玩家
	
	Json::Value val;
	reader.parse(totalLog.extra_data2, val);					// 添加牌桌用时
	val["game_time"] = totalLog.use_time;						// 牌桌用时
	
	cb.sdata8 = w.write(val);									// 牌桌附加数据2
	
	// 组局当前轮次
	sCenterBattleMgr.UpdateCenterBattleCurrloop(cb_info.cb_id, totalLog.loop_id);
	
	if(!bFind)
	{// 添加记录
		AddCenterBattleLog(cb);
	}
	else
	{// 更新记录
		UpdateCenterBattleLog(cb);
	}
	
	return true;
}

// 俱乐部房间组局记录（将一个房间的N个玩家的数据全部记录在一起）
bool CenterBattleLogManager::AddCenterClubRoomBattleLog(BattleTotalLog totalLog)
{
WGS_CENTERBATTLELOG_LOCK
	CenterBattleLog cb;
	CenterBattle cb_info;
	sCenterBattleMgr.GetCenterBattle(totalLog.cb_id, &cb_info);
	
	std::list<CenterBattleLog> logs;
	if(totalLog.club_room_id)
		GetCenterBattleLogList(&logs, "club_id = %u and club_room_id = %u and type = %u", totalLog.club_id, totalLog.club_room_id, enCenterBattleLogType_ClubRoomLog);
	else
		GetCenterBattleLogList(&logs, "club_id = %u and cb_id = %u and type = %u", totalLog.club_id, totalLog.cb_id, enCenterBattleLogType_ClubRoomLog);
	
	bool bFind = logs.size();
	if(bFind)
	{// 找到记录，准备更新数据
		cb = *logs.begin();
		cb.data4 = cb_info.curr_loop;			// 当前局数
	}
	else
	{// 创建数据
		cb.cb_id = totalLog.cb_id;
		cb.gz_id = cb_info.gz_id;					// 分区ID
		cb.game_id = cb_info.game_id;				// 游戏ID
		cb.club_id = totalLog.club_id;				// 俱乐部ID
		cb.club_room_id = totalLog.club_room_id;	// 俱乐部房间ID
		
		cb.type = enCenterBattleLogType_ClubRoomLog;
		
		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(cb_info.reg_from, cb_info.game_id, cb_info.mode);	// 游戏名
		cb.sdata2 = cb_info.sdata2;				// 玩法
		cb.sdata3 = cb_info.name;				// 房主名
		cb.sdata4 = cb_info.head;				// 房主头像
		cb.sdata7 = cb_info.join_code;			// 进入验证码
		
		cb.data4 = cb_info.curr_loop;			// 当前局数
		cb.data5 = cb_info.limit_loop;			// 总局数
		cb.data12 = cb_info.mode;				// 游戏玩法模式
		
		cb.create_time = totalLog.create_time;	// 创建时间
	}
	
	stCenterBattleOpenCoins stCOC = sXmlDataMgr.GetCenterBattleOpenCoins(cb_info.reg_from, cb_info.game_id, cb_info.limit_loop, enCenterBattleLimitType_Loop, cb_info.mode);
	
	Json::Reader reader;
	Json::FastWriter w;
	Json::Value val_player;
	reader.parse(cb.sdata5, val_player);			// 玩家一局中输赢json
	
	std::vector<CenterBattlePlayerWinLose>::iterator iter,ei = totalLog.player_winLose.end();
	for(iter = totalLog.player_winLose.begin(); iter!=ei; ++iter)
	{
		uint32 curr_pump = (*iter).winLoseScore > 1 ? uint32(ceil((*iter).winLoseScore * stCOC.fDjPercent)) : 0;
		
		bool bFindChar = false;
		for (Json::Value::iterator iterVal=val_player.begin(); iterVal!=val_player.end(); ++iterVal)
		{
			if((*iter).platform_id == (*iterVal)["pid"].asUInt())
			{// 更新角色数据
				bFindChar = true;
				
				(*iterVal)["winlose"] = (*iterVal)["winlose"].asInt() + (*iter).winLoseScore;	// 输赢更新
				(*iterVal)["player_count"] = (*iterVal)["player_count"].asUInt() + 1;			// 游戏局数增加
				
				// 更新玩家单个房间的输赢
				sCenterClubMemberMgr.SetClubRoomWinlose(totalLog.club_id, totalLog.club_room_id, (*iter).platform_id, (*iter).winLoseScore);
				
				uint32 total_pump =  0;
				if((*iterVal)["winlose"].asInt() > 0)
					total_pump = ceil((*iterVal)["winlose"].asInt() * stCOC.fDjPercent);
				
				(*iterVal)["total_pump"] = total_pump;											// 对局费，抽水增加
				break;
			}
		}
		
		char str[256] = "";
		sprintf(str, "%u", (*iter).platform_id);
		
		if(!bFindChar)
		{// 添加角色数据
			val_player[str]["pid"] = (*iter).platform_id;								// PID
			val_player[str]["name"] = string_url_encode((*iter).player_nick); 			// 昵称
			val_player[str]["desc"] = string_url_encode((*iter).player_desc);			// 头像
			val_player[str]["winlose"] = (*iter).winLoseScore;							// 输赢积分
			val_player[str]["player_count"] = 1;										// 总游戏局属
			val_player[str]["total_pump"] = curr_pump;									// 对局费/抽水
			
			uint32 takein_coins = sCenterClubMemberMgr.GetMemberTakeinCoins(cb_info.club_id, (*iter).platform_id);
			if(takein_coins)
				val_player[str]["takein_coins"] = takein_coins;
			
			// 更新玩家单个房间的输赢
			sCenterClubMemberMgr.SetClubRoomWinlose(totalLog.club_id, totalLog.club_room_id, (*iter).platform_id, (*iter).winLoseScore);
		}
		
		// 修改玩家俱乐部记录
		sCenterClubMemberMgr.MemberComplateGame(cb_info.club_id, (*iter).platform_id, (*iter).winLoseScore, curr_pump);
	}
	
	cb.sdata5 = w.write(val_player);							// 一局中总输赢
	
	Log.Debug("CenterBattleLogManager::AddCenterClubRoomBattleLog","club_id[%u] club_room_id[%u] bFind[%u]", cb.club_id, cb.club_room_id, bFind);
	if(!bFind)
		AddCenterBattleLog(cb);		// 添加记录
	else
		UpdateCenterBattleLog(cb);	// 更新记录
	
	return true;
}

// 金币场轮次战绩记录
bool CenterBattleLogManager::AddCoinsLoopLog(CoinsLoopLog coins_log, uint8 pos)
{
WGS_CENTERBATTLELOG_LOCK
	CenterBattleLog cb;
	
	cb.cb_id = coins_log.channel_id;
	cb.gz_id = coins_log.gz_id;
	cb.game_id = coins_log.game_id;
	
	cb.type = enCenterBattleLogType_CoinsLoopLog;	// 日志类型-每轮详细输赢
	
	cb.data1 = coins_log.base_coins;				// 底分
	cb.data6 = coins_log.bHaveVedio;				// 是否录像（0 否 1 是）
	
	cb.sdata1 = coins_log.game_name;				// 游戏名
	
	Json::Reader reader;
	Json::FastWriter w;
	Json::Value val, valPay;
	
	std::vector<CenterBattlePlayerWinLose>::iterator iter,ei = coins_log.player_winLose.end();
	for(iter = coins_log.player_winLose.begin(); iter!=ei; ++iter)
	{
		String strPid = StringConverter::toString((*iter).platform_id);
		uint32 pid = (*iter).platform_id;
		
		val["players"][strPid]["pid"] = pid;										// PID
		val["players"][strPid]["name"] = string_url_encode((*iter).player_nick); 	// 昵称
		val["players"][strPid]["desc"] = string_url_encode((*iter).player_desc);	// 头像
		val["players"][strPid]["winlose"] = (*iter).winLoseScore;					// 输赢积分
		val["players"][strPid]["json_data"] = (*iter).json_data;					// 详细输赢
		
		val["players"][strPid]["pos"] = pos;										// 玩家位置
		pos++;
	}
	
	val["data"] = coins_log.extra_data;			// 游戏输赢明细
	
	cb.sdata5 = w.write(val);					// 输赢详细
	cb.create_time = sGLMgr.GetCurDateTime();	// 结束时间
	cb.record_data = coins_log.record_data;		// 游戏流程记录
	
	for(iter = coins_log.player_winLose.begin(); iter!=ei; ++iter)
	{
		cb.data9 = (*iter).winLoseScore;
		cb.src_pid = (*iter).platform_id;
		AddCenterBattleLog(cb);
	}
	
	return true;
}

// 获取玩家牌桌记录 cb_id = 0 表示取所有能取的
bool CenterBattleLogManager::GetPlayerBattleLogs(CharPtr & pChr, const uint32 & cb_id)
{
	if(pChr.isNull())
		return false;
	
WGS_CENTERBATTLELOG_LOCK
	// 以组局的轮次data3来进行group by，取得一条记录就行
	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "cb_id = %u and type = %u group by data3", cb_id, enCenterBattleLogType_PlayerWinLose);
	
	WorldPacket packet;
	if(sProtocolsMgr.CreatePlayerCenterBattleLogsPacket(&packet, logs))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 获取未读消息数量
uint32 CenterBattleLogManager::GetBattleLogsDBCount(const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	
	FieldRows fieldRows;
	sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fieldRows, "count(`battle_log_id`) as `count`", sql);
	return fieldRows.size();
}

// 获取组局牌局记录 cb_id = 0 表示取所有能取的  00FA
bool CenterBattleLogManager::GetBattleLogs(CharPtr & pChr, const uint32 & cb_id, const uint32 & offset, const uint32 & num)
{
	if(pChr.isNull())
		return false;
	
WGS_CENTERBATTLELOG_LOCK
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
	{// 因为是发包，不在线就可以返回了，不需要去load
		return false;
	}
	
	uint32 days = sXmlDataMgr.GetConfXMLValue("CENTER_BATTLELOG_FARDAYS");
	if(!days)
		days = 7;
	
	time_t time_far = time(0) - 86400 * days;
	String farDays = sTools.GetCurDateTime(time_far);
	uint32 real_num = num;
	
	Log.Debug("CenterBattleLogManager::GetBattleLogs","cb_id[%u] offset[%u] num[%u]", cb_id, offset, num);
	
	uint32 total_count = 0;
	std::list<CenterBattleLog> logs;
	if(cb_id)
	{// 找单个指定的组局数据
		GetCenterBattleLogList(&logs, "cb_id = %u and type = %u", cb_id, enCenterBattleLogType_BattleTotalInfo);
		total_count = logs.size();
	}
	else
	{// 找玩家一定数量的组局记录
		
		// 记录总数
		total_count = GetBattleLogsDBCount("src_pid = %u and cb_id > 0 and data7 > 0 and type = %u group by cb_id", pUser->getUInt32Field("platform_id"), 
														enCenterBattleLogType_PlayerWinLose);
		
		if(real_num == 0)
			real_num = sXmlDataMgr.GetConfXMLValue("CENTER_BATTLELOG_MAXNUM");
		
		// 偏移索引版本
		std::list<CenterBattleLog> countLogs;
		GetCenterBattleLogList(&countLogs, "src_pid = %u and cb_id > 0 and data7 > 0 and type = %u group by cb_id order by create_time desc limit %u, %u", 
									pUser->getUInt32Field("platform_id"), enCenterBattleLogType_PlayerWinLose, offset, real_num);
		
		real_num = countLogs.size();
		if(countLogs.size())
		{// 找到玩家玩过的组局后，查找组局的统计记录
			uint8 index = 0;
			String strCBID;
			std::list<CenterBattleLog>::iterator iter,ei = countLogs.end();
			for(iter = countLogs.begin(); iter!=ei; ++iter)
			{
				++index;
				strCBID += StringConverter::toString((*iter).cb_id);
				if(index != countLogs.size())
					strCBID += ",";
			}
			
			GetCenterBattleLogList(&logs, "cb_id in (%s) and type = %u order by create_time desc", strCBID.c_str(), enCenterBattleLogType_BattleTotalInfo);
		}
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterBattleLogPacket(&packet, logs, cb_id, total_count, offset))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 获取俱乐部历史战绩
bool CenterBattleLogManager::GetClubBattleLogs(CharPtr & pChr, const uint32 & club_id, const uint32 & offset, const uint16 & num)
{
	if(pChr.isNull())
		return false;
	
	FieldRows fieldRows;
	sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fieldRows, "count(`battle_log_id`) as `count`", "club_id = %u and type = %u", club_id, enCenterBattleLogType_ClubRoomLog);
	
	uint32 total_num = 0;
	if(fieldRows.size())
	{
		std::map<String,Field>::iterator itMap, eiMap = fieldRows[0].end();
		for(itMap = fieldRows[0].begin(); itMap!=eiMap; ++itMap)
		{
			total_num = (itMap->second).GetUInt32();
		}
	}
	
	Log.Debug("CenterBattleLogManager::GetClubBattleLogs","char[%u] club_id[%u] offset[%u] num[%u]", pChr->getHandle(), club_id, offset, num);
	uint32 require_count = num;
	if(require_count == 0)
		require_count = total_num;
	
	Log.Debug("CenterBattleLogManager::GetClubBattleLogs","char[%u] club_id[%u] require_count[%u]", pChr->getHandle(), club_id, require_count);
	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "club_id = %u and type = %u order by create_time desc limit %u, %u", club_id, enCenterBattleLogType_ClubRoomLog, offset, require_count);
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateClubBattleHistoryPacket(&packet, club_id, offset, fieldRows.size(), logs))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	return true;
}

// 获得俱乐部周期战绩排名
bool CenterBattleLogManager::GetClubBattleHistoryLogs(CharPtr & pChr, const uint32 & club_id, const uint8 & day)
{
	if(pChr.isNull())
		return false;
	
WGS_CENTERBATTLELOG_LOCK
	stClubHistoryBattle stSendCHB;
	uint32 time_now = time(0);
	bool bNeedQuery = true;
	if(day > 0)
	{// 查历史 直接去缓存里面取
		std::map<uint32, std::vector<stClubHistoryBattle> >::iterator fit = m_mapClubBattleHistory.find(club_id);
		if(fit != m_mapClubBattleHistory.end())
		{// 看是读取缓存数据还是重新SQL
			std::vector<stClubHistoryBattle>::iterator iter, ei = fit->second.end();
			for(iter = fit->second.begin(); iter!=ei; ++iter)
			{
				if((*iter).day == day && sGLMgr.IsSameDate(time_now, (*iter).query_time))
				{// 查询同一个历史，今天已经查询过，不用再次查询
					bNeedQuery = false;
					stSendCHB = *iter;
					
					// 发包
					WorldPacket packet;
					if(sProtocolsMgr.CreateClubHistoryChengJiPacket(&packet, stSendCHB))
						sGLMgr.SendProtocolsToChr(pChr, &packet);
					
					return true;
				}
			}
		}
	}
	
	if(bNeedQuery)
	{
		stSendCHB.club_id = club_id;
		stSendCHB.query_time = time_now;		// 查询时间（用于判断历史成绩是否需要重新sql）
		stSendCHB.day = day;					// 查询天数
		
		// 系统消息要提取出来
		FieldRows rowsHistory, rowsUse;
		
		// 查询成绩排行
		sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &rowsHistory, "count(*),sum(data9),src_pid,user_nick", 
									"status < 255 and club_id = %u and type = %u and TIMESTAMPDIFF(day, create_time, NOW()) <= %u GROUP BY src_pid", 
									club_id, enCenterBattleLogType_PlayerWinLose, day);
		
		// 查询创建局数
		sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, "center_battle", &rowsUse, "count(*) as count",
													"`club_id` = %u and TIMESTAMPDIFF(day, create_time, NOW()) <= %u", club_id, day);
		
		Log.Debug("CenterBattleLogManager::GetClubBattleHistoryLogs","char[%u] battle_count[%u]", pChr->getHandle(), stSendCHB.battle_count);
		
		FieldRows::iterator itUse, eiUse = rowsUse.end();
		for(itUse = rowsUse.begin(); itUse!=eiUse; ++itUse)
		{
			std::map<String,Field>::iterator itMapC, eiMapC = (*itUse).end();
			for(itMapC = (*itUse).begin(); itMapC!=eiMapC; ++itMapC)
			{
				stSendCHB.battle_count = (itMapC->second).GetUInt32();		// 游戏局数
				Log.Debug("CenterBattleLogManager::GetClubBattleHistoryLogs","char[%u] battle_count[%u] rowsUse size[%u] first[%s]", pChr->getHandle(), stSendCHB.battle_count, rowsUse.size(), (itMapC->first).c_str());
			}
		}
		
		rowsUse.clear();
		// 查询房卡消耗
		sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, "center_battle", &rowsUse, "sum(`data2`) as count",
													"`club_id` = %u and `data1` = %u and TIMESTAMPDIFF(day, create_time, NOW()) <= %u", 
													club_id, ItemModel_DiamondOpen ,day);
		
		std::map<String,Field>::iterator itMapS, eiMapS = rowsUse[0].end();
		for(itMapS = rowsUse[0].begin(); itMapS!=eiMapS; ++itMapS)
		{
			stSendCHB.use_fangka = (itMapS->second).GetUInt32();			// 房卡消耗
			Log.Debug("CenterBattleLogManager::GetClubBattleHistoryLogs","char[%u] use_fangka[%u]", pChr->getHandle(), stSendCHB.use_fangka);
		}
		
		// 成绩排行查询
		if(rowsHistory.size())
		{
			FieldRows::iterator iter, ei = rowsHistory.end();
			for(iter = rowsHistory.begin(); iter!=ei; ++iter)
			{
				stClubHistoryBattlePlayer stPlayer;
				std::map<String,Field>::iterator itMap, eiMap = (*iter).end();
				for(itMap = (*iter).begin(); itMap!=eiMap; ++itMap)
				{
					if(!(itMap->first).compare("count(*)"))
					{// 游戏局数
						stPlayer.count = (itMap->second).GetUInt32();
					}
					else if(!(itMap->first).compare("sum(data9)"))
					{// 输赢
						stPlayer.winLose = (itMap->second).GetInt32();
					}
					else if(!(itMap->first).compare("src_pid"))
					{// 玩家PID
						stPlayer.src_pid = (itMap->second).GetInt32();
					}
					else if(!(itMap->first).compare("user_nick"))
					{// 玩家昵称
						stPlayer.nick = (itMap->second).GetString();
					}
				}
				
				stSendCHB.vPlayers.push_back(stPlayer);
				Log.Debug("CenterBattleLogManager::GetClubBattleHistoryLogs","club_id[%u] day[%u] vPlayers size[%u]", club_id, day, stSendCHB.vPlayers.size());
			}
		}
		
		std::map<uint32, std::vector<stClubHistoryBattle> >::iterator fit = m_mapClubBattleHistory.find(club_id);
		if(fit != m_mapClubBattleHistory.end())
		{// 有俱乐部记录
			
			bool bFind = false;
			std::vector<stClubHistoryBattle>::iterator iter, ei = fit->second.end();
			for(iter = fit->second.begin(); iter!=ei; ++iter)
			{
				if((*iter).day == day)
				{// 找到查询指定天数的数据
					(*iter) = stSendCHB;
					bFind = true;
					break;
				}
			}
		}
		else
		{// 没有俱乐部记录
			std::vector<stClubHistoryBattle> vBattles;
			vBattles.push_back(stSendCHB);
			
			m_mapClubBattleHistory.insert(std::make_pair(club_id, vBattles));
		}
	}
	
	// 发包
	WorldPacket packet;
	if(sProtocolsMgr.CreateClubHistoryChengJiPacket(&packet, stSendCHB))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	return true;
}

// 获取即时输赢信息
bool CenterBattleLogManager::GetCurrentBattleWinLose(CharPtr & pChr, const uint32 & cb_id)
{
	if(pChr.isNull() || !cb_id)
		return false;
	
	// 没有数据 发送当前玩家列表
	CenterBattle cb;
	if(!sCenterBattleMgr.GetCenterBattle(cb_id, &cb))
		return false;
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCurrentCenterBattleWinLosePacket(&packet, cb))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 获取组局玩家即时信息
bool CenterBattleLogManager::GetCurrentBattlePlayerInfo(CharPtr & pChr, const uint32 & cb_id)
{
	if(pChr.isNull() || !cb_id)
		return false;
	
	// 没有数据 发送当前玩家列表
	CenterBattle cb;
	if(!sCenterBattleMgr.GetCenterBattle(cb_id, &cb))
		return false;
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterBattlePlayerInfoPacket(&packet, cb))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 获得一轮记录
bool CenterBattleLogManager::GetBattleLoopLog(CharPtr & pChr, const uint32 & cb_id, const uint8 & loop)
{
	if(pChr.isNull() || !cb_id)
		return false;
	
	WorldPacket packet;
	CenterBattleLog log;
	std::list<CenterBattleLog> logs;
	if(!GetCenterBattleLogList(&logs, "cb_id = %u and data3 = %u and type = %u group by data3 order by battle_log_id desc", cb_id, loop, enCenterBattleLogType_PlayerWinLose))
	{// 没获取到数据告诉客户端没有记录
		if(sProtocolsMgr.CreateCenterBattleSingleLoopLogPacket(&packet, cb_id, loop, log))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
		return false;
	}
	
	log = *logs.begin();
	if(sProtocolsMgr.CreateCenterBattleSingleLoopLogPacket(&packet, cb_id, loop, log))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 获得一轮记录
bool CenterBattleLogManager::GetBattleVedio(CharPtr & pChr, const uint32 & cb_id, const uint8 & loop)
{
	if(pChr.isNull() || !cb_id)
		return false;
	
	WorldPacket packet;
	CenterBattleLog log;
	std::list<CenterBattleLog> logs;
	if(!GetCenterBattleLogList(&logs, "cb_id = %u and data3 = %u and type = %u group by data3 order by battle_log_id desc", cb_id, loop, enCenterBattleLogType_PlayerWinLose))
	{// 没获取到数据告诉客户端没有记录
		if(sProtocolsMgr.CreateGameRecordVedio(&packet, cb_id, loop, ""))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
		return false;
	}
	
	log = *logs.begin();
	if(sProtocolsMgr.CreateGameRecordVedio(&packet, cb_id, loop, log.record_data, log.data12))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	return true;
}

// 结束记录用时
bool CenterBattleLogManager::CountBattleLogUseTime(const uint32 & cb_id)
{
	if(!cb_id)
		return false;
	
	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "cb_id = %u and type = %u", cb_id, enCenterBattleLogType_BattleTotalInfo);
	if(logs.empty())
		return false;
	
	CenterBattleLog cb = *logs.begin();
	cb.data8 = time(0) - cb.data3;					// 游戏最终用时
	
	return UpdateCenterBattleLog(cb);
}

// 查询某局记录
uint8 CenterBattleLogManager::QueryCenterBattleLog(String strData, String & extra_data, String & share_info)
{
	Json::Value val, valData;
	Json::Reader reader;
	reader.parse(strData, val);
	
	String join_code = "";
	if(val.isMember("join_code"))
		join_code = val["join_code"].asString();
	
	String strPlatform = "";
	if(val.isMember("platform"))
		strPlatform = val["platform"].asString();
	
	Log.Debug("CenterBattleLogManager::QueryCenterBattleLog","strData[%s] extra_data[%s]", strData.c_str(), extra_data.c_str());
	if(join_code.size())
	{// 找单个指定的组局数据
		std::list<CenterBattle> lstCB;
		sCenterBattleMgr.GetCenterBattleList(&lstCB, "join_code = %s order by create_time desc limit 1", join_code.c_str());
		if(lstCB.empty())
			return enQueryCBDResult_NoThisRoom;
		
		CenterBattle cb = *lstCB.begin();
		
		valData["cb_id"] = cb.cb_id;			// 组局ID
		valData["gz_id"] = cb.gz_id;			// 分区ID
		valData["game_id"] = cb.game_id;		// 游戏ID
		valData["room_status"] = cb.status;		// 房间状态（3 未开始 4 已开始 255 已结束）
		valData["join_code"] = cb.join_code;	// 房间ID
		
		Json::Reader reader;
		Json::Value val;
		
		uint8 index = 0;
		reader.parse(cb.player, val);
		for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
		{
			Json::Value valPData;
			valPData["pid"] = (*iterVal)["pid"].asUInt();
			valPData["name"] = (*iterVal)["name"].asString();
			valPData["desc"] = (*iterVal)["desc"].asString();
			valPData["winlose"] = (*iterVal)["winlose"].asInt();
			valPData["player_count"] = (*iterVal)["player_count"].asUInt();
			
			valData["players"][index++] = valPData;
		}
		
		Json::FastWriter w;
		extra_data = w.write(valData);
		
		share_info = sGLMgr.GetWXShareInfo(cb, strPlatform);
		return enQueryCBDResult_Sucess;
	}
	
	return enQueryCBDResult_Failed;
}

// 获得玩家单局记录列表 2021
void CenterBattleLogManager::GetPlayerSingleLogs(CharPtr & pChr, const uint32 & offset, const uint32 & require_count)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	uint32 total_count = 0;
	
	FieldRows fieldRows;
	sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fieldRows, "count(`battle_log_id`) as `count`", 
										"src_pid = %u and (type = %u or type = %u) and data7 = 0", pid, enCenterBattleLogType_PlayerWinLose, enCenterBattleLogType_CoinsLoopLog);
	
	if(fieldRows.size())
	{
		std::map<String,Field>::iterator itMap, eiMap = fieldRows[0].end();
		for(itMap = fieldRows[0].begin(); itMap!=eiMap; ++itMap)
		{
			total_count = (itMap->second).GetUInt32();
		}
	}
	
	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "src_pid = %u and (type = %u or type = %u)  and data7 = 0 order by create_time desc limit %u, %u", 
								pid, enCenterBattleLogType_PlayerWinLose, enCenterBattleLogType_CoinsLoopLog, offset, require_count);
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterBattlePlayerSingleLogPacket(&packet, offset, total_count, logs))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 得到玩家赛区记录
void CenterBattleLogManager::GetPlayerMatchZoneLogs(CharPtr & pChr, const uint32 & zone_id, const uint32 & offset, const uint32 & require_count)
{
	if(pChr.isNull())
		return ;

	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;

	uint32 pid = pUser->getUInt32Field("platform_id");
	uint32 total_count = 0;
	
	FieldRows fieldRows;
	sDataMgr.queryDatas(DataManager::DatabaseTypeCenter, DB_NAME_CENTERBATTLELOG, &fieldRows, "count(`battle_log_id`) as `count`", 
										"src_pid = %u and (type = %u or type = %u) and data10 = %u", pid, enCenterBattleLogType_PlayerWinLose, enCenterBattleLogType_CoinsLoopLog, zone_id);
	
	if(fieldRows.size())
	{
		std::map<String,Field>::iterator itMap, eiMap = fieldRows[0].end();
		for(itMap = fieldRows[0].begin(); itMap!=eiMap; ++itMap)
		{
			total_count = (itMap->second).GetUInt32();
		}
	}
	
	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "src_pid = %u and (type = %u or type = %u)  and data10 = %u order by create_time desc limit %u, %u", 
								pid, enCenterBattleLogType_PlayerWinLose, enCenterBattleLogType_CoinsLoopLog, zone_id, offset, require_count);
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterBattleMatchZoneLogsPacket(&packet, zone_id, offset, total_count, logs))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 组局每轮输赢记录
bool CenterBattleLogManager::AddCenterMatchLoopWinLoseLog(BattleTotalLog logInfo, uint8 pos)
{
#ifdef CENTERMATCH
	WGS_CENTERBATTLELOG_LOCK
		CenterBattleLog cb;
	CenterMatch cm_info;
	sCenterMatchMgr.GetCenterMatch(logInfo.cm_id, &cm_info);

	if (logInfo.cm_id)
	{
		cb.cb_id = cm_info.cm_id;
		cb.gz_id = cm_info.gz_id;
		cb.game_id = cm_info.game_id;

		cb.data1 = cm_info.base_coins;	// 底分
		cb.data2 = cm_info.fan_coins;	// 翻分
		cb.data5 = cm_info.pid;			// 房主PID
		cb.data7 = cm_info.limit_loop;	// 总局数
	}
	else
	{
		cb.cb_id = logInfo.cm_id;
		cb.gz_id = logInfo.gz_id;
		cb.game_id = logInfo.game_id;
		cb.club_id = logInfo.jd_id;
		cb.club_room_id = logInfo.club_room_id;

		cb.data1 = logInfo.base_coins;	// 底分
		cb.data2 = logInfo.fan_coins;	// 翻分
		cb.data5 = logInfo.owner_pid;	// 房主PID
		cb.data8 = logInfo.channel_id;	// 牌局ID
	}

	cb.type = enCenterBattleLogType_CenterMatchPlayerWinLose;			// 日志类型-每轮详细输赢

	cb.data3 = logInfo.loop_id;		// 轮次ID
	cb.data4 = logInfo.use_time;	// 使用时间
	cb.data6 = logInfo.bHaveVedio;	// 是否拥有录像
	cb.data12 = logInfo.mode;		// 游戏玩法

	if (logInfo.agent_id)
		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(logInfo.agent_id, logInfo.game_id, logInfo.mode);
	else
		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(cm_info.reg_from, cm_info.game_id, cm_info.mode);	// 游戏名

	cb.sdata2 = cm_info.battle_name;
	cb.sdata3 = cm_info.name;
	cb.sdata4 = cm_info.head;

	Json::Reader reader;
	Json::FastWriter w;
	Json::Value val, valPay;

	std::vector<CenterBattlePlayerWinLose>::iterator iter, ei = logInfo.player_winLose.end();
	for (iter = logInfo.player_winLose.begin(); iter != ei; ++iter)
	{
		String strPid = StringConverter::toString((*iter).platform_id);
		uint32 pid = (*iter).platform_id;

		val["players"][strPid]["pid"] = pid;										// PID
		val["players"][strPid]["name"] = string_url_encode((*iter).player_nick); 	// 昵称
		val["players"][strPid]["desc"] = string_url_encode((*iter).player_desc);	// 头像
		val["players"][strPid]["winlose"] = (*iter).winLoseScore;					// 输赢积分
		val["players"][strPid]["json_data"] = (*iter).json_data;					// 详细输赢

																					// 更新玩家总输赢积分 cr_users.total_winlose_score
		CRUser cru;
		if (sCRUsersMgr.GetCRUser(pid, &cru))
		{
			Fields fields;
			fields["total_winlose_score"] = cru.total_winlose_score + (*iter).winLoseScore;
			sCRUsersMgr.UpdateCRUser(pid, &fields);
		}

		//============纯json版=======================
		// Json::Value val2;
		// reader.parse((*iter).json_data, val2);
		// val["players"][strPid]["json_data"] = val2;							// 详细输赢

		val["players"][strPid]["pos"] = pos;								// 玩家位置
		pos++;
	}

	val["data"] = logInfo.extra_data;			// 游戏输赢明细

												//===============纯json版=====================
												// Json::Value val3;
												// reader.parse(logInfo.extra_data, val3);	
												// val["data"] = val3;						// 游戏输赢明细						

	cb.sdata5 = w.write(val);					// 输赢详细

	cb.create_time = sGLMgr.GetCurDateTime();	// 结束时间
	cb.record_data = logInfo.record_data;		// 游戏流程记录

	bool bFzPlay = false;
	for (iter = logInfo.player_winLose.begin(); iter != ei; ++iter)
	{// 房主在游戏
		if ((*iter).platform_id == cm_info.pid)
			bFzPlay = true;

		cb.data9 = (*iter).winLoseScore;
		cb.src_pid = (*iter).platform_id;
		cb.user_nick = (*iter).player_nick;
		AddCenterBattleLog(cb);
	}


#endif // CENTERMATCH



	return true;
}

// 组局整体记录（以一局的一轮为单位存储日志）
bool CenterBattleLogManager::AddCenterMatchLoopTotalLog(BattleTotalLog totalLog)
{
#ifdef CENTERMATCH
	WGS_CENTERBATTLELOG_LOCK
		CenterBattleLog cb;
	CenterMatch cm_info;
	sCenterMatchMgr.GetCenterMatch(totalLog.cb_id, &cm_info);

	

	std::list<CenterBattleLog> logs;
	GetCenterBattleLogList(&logs, "cb_id = %u and type = %u", totalLog.cm_id, enCenterBattleLogType_CenterMatchLoopTotalInfo);

	bool bFind = logs.size();
	if (logs.size())
		cb = *logs.begin();

	if (bFind)
	{// 更新数据
		cb.data4++;							// 总轮数增加
		cb.data8 = time(0) - cb.data3;		// 游戏最终用时（每一把 结算）
	}
	else
	{// 创建数据
		cb.cb_id = totalLog.cm_id;
		cb.gz_id = cm_info.gz_id;			// 分区ID
		cb.game_id = cm_info.game_id;		// 游戏ID
		cb.club_id = totalLog.jd_id;		// 俱乐部ID
		cb.club_room_id = totalLog.channel_id;		// 俱乐部ID

		cb.src_pid = cm_info.pid;			// 房主PID

		cb.type = enCenterBattleLogType_CenterMatchLoopTotalInfo;			// 一局日志

		cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(cm_info.reg_from, cm_info.game_id, cm_info.mode);	// 游戏名
		cb.sdata2 = cm_info.sdata2;			// 玩法
		cb.sdata3 = cm_info.battle_name;	// 比赛名称
		cb.sdata4 = cm_info.head;			// 房主头像
		cb.sdata7 = cm_info.join_code;		// 进入验证码

		cb.data1 = cm_info.base_coins;		// 底分
		cb.data2 = cm_info.fan_coins;		// 翻分
		cb.data3 = totalLog.use_time;		// 游戏创建时间
		cb.data4 = 1;						// 总局数
		cb.data5 = cm_info.limit_loop;		// 总局数
		cb.data8 = time(0) - cb.data3;		// 游戏最终用时

		cb.data11 = cm_info.sponsor_id;		// 赞助商id
		cb.data12 = cm_info.match_mode;			// 游戏玩法

		cb.create_time = totalLog.create_time;	// 创建时间
	}

	Json::Reader reader;
	Json::FastWriter w;
	Json::Value val_player, val_maxInfo, valData2;
	reader.parse(cb.sdata5, val_player);			// 玩家一局中输赢json
	reader.parse(totalLog.extra_data2, valData2);	// 牌局附加数据2（存放庄家，用时等，游戏比较特殊的信息）

	valData2["game_time"] = cb.data8;				// 游戏用时
	totalLog.extra_data2 = w.write(valData2);		// 牌桌附加数据2

	// 赢最多，输最多
	int max_winScore = 0;
	int max_loseScore = 0;

	uint32 max_winPid = 0;
	uint32 max_losePid = 0;

	std::map<uint32, int32> mapPlayerWinLose;
	for (Json::Value::iterator iterVal = val_player.begin(); iterVal != val_player.end(); ++iterVal)
	{
		mapPlayerWinLose.insert(std::make_pair((*iterVal)["pid"].asUInt(), (*iterVal)["winlose"].asInt()));
	}

	std::vector<CenterBattlePlayerWinLose>::iterator iter, ei = totalLog.player_winLose.end();
	for (iter = totalLog.player_winLose.begin(); iter != ei; ++iter)
	{
		if ((*iter).winLoseScore > 0)
		{// 赢家
		 // 总赢
			cb.data6 += (*iter).winLoseScore;
			// 最大赢钱
			if (cb.data7 < uint32((*iter).winLoseScore))
				cb.data7 = (*iter).winLoseScore;

			if (cb.data9 < (*iter).winLoseScore)
			{// 本局最大赢钱
				cb.data9 = (*iter).winLoseScore;
			}

			// 总赢钱
			cb.data10 += (*iter).winLoseScore;
		}

		bool bFindChar = false;
		for (Json::Value::iterator iterVal = val_player.begin(); iterVal != val_player.end(); ++iterVal)
		{
			if ((*iter).platform_id == (*iterVal)["pid"].asUInt())
			{
				bFindChar = true;
				// (*iterVal)["player_status"] = enCenterBattlePlayerStatus_Free;		// 现在模式不需要修改玩家状态
				(*iterVal)["winlose"] = (*iterVal)["winlose"].asInt() + (*iter).winLoseScore;

				Json::Value valEx;
				Json::Reader reader;
				reader.parse((*iter).json_data, valEx);

				if (valEx.isMember("banker_loop"))
				{// 有局数直接赋值
					(*iterVal)["player_count"] = valEx["banker_loop"].asUInt();
				}
				else
				{// 没有局数，就累加
					(*iterVal)["player_count"] = (*iterVal)["player_count"].asUInt() + 1;
				}

				(*iterVal)["json_data"] = (*iter).json_data;							// 详细输赢

				std::map<uint32, int32>::iterator fit = mapPlayerWinLose.find((*iterVal)["pid"].asUInt());
				if (fit == mapPlayerWinLose.end())
					mapPlayerWinLose.insert(std::make_pair((*iterVal)["pid"].asUInt(), (*iterVal)["winlose"].asInt()));
				else
					fit->second = (*iterVal)["winlose"].asInt();

				break;
			}
		}

		char str[256] = "";
		sprintf(str, "%u", (*iter).platform_id);

		if (!bFindChar)
		{
			val_player[str]["pid"] = (*iter).platform_id;			// PID
			val_player[str]["cid"] = (*iter).char_id;				// CID
			val_player[str]["name"] = string_url_encode((*iter).player_nick); 			// 昵称
			val_player[str]["desc"] = string_url_encode((*iter).player_desc);			// 头像
			val_player[str]["winlose"] = (*iter).winLoseScore;		// 输赢积分
			val_player[str]["player_count"] = 1;					// 总游戏局属
			val_player[str]["player_status"] = enCenterBattlePlayerStatus_Free;			// 角色状态（空闲 游戏中 离开）
			val_player[str]["json_data"] = (*iter).json_data;							// 详细输赢
			uint32 takein_coins = sCenterClubMemberMgr.GetMemberTakeinCoins(0, (*iter).platform_id);
			if (takein_coins)
				val_player[str]["takein_coins"] = takein_coins;

			std::map<uint32, int32>::iterator fit = mapPlayerWinLose.find((*iter).platform_id);
			if (fit == mapPlayerWinLose.end())
				mapPlayerWinLose.insert(std::make_pair((*iter).platform_id, (*iter).winLoseScore));
			else
				fit->second = (*iter).winLoseScore;
		}
	}

	std::map<uint32, int32>::iterator itWL, eiWL = mapPlayerWinLose.end();
	for (itWL = mapPlayerWinLose.begin(); itWL != eiWL; ++itWL)
	{
		if (itWL->second > 0)
		{
			if (max_winScore < itWL->second)
			{// 赢最多
				max_winScore = itWL->second;
				max_winPid = itWL->first;
			}
		}
		else if (itWL->second < 0)
		{
			if (max_loseScore > itWL->second)
			{// 输最多
				max_loseScore = itWL->second;
				max_losePid = itWL->first;
			}
		}
	}

	val_maxInfo["win_max"]["pid"] = max_winPid;
	val_maxInfo["lose_max"]["pid"] = max_losePid;

	cb.sdata5 = w.write(val_player);							// 一局中总输赢
	cb.sdata6 = w.write(val_maxInfo);							// 最佳数据玩家

	Json::Value val;
	reader.parse(totalLog.extra_data2, val);					// 添加牌桌用时
	val["game_time"] = totalLog.use_time;						// 牌桌用时

	cb.sdata8 = w.write(val);									// 牌桌附加数据2

															

	if (!bFind)
	{// 添加记录
		AddCenterBattleLog(cb);
	}
	else
	{// 更新记录
		UpdateCenterBattleLog(cb);
	}

#endif // CENTERMATCH
	return true;

}

// 整体记录（以整场为单位存储日志）
bool CenterBattleLogManager::AddCenterMatchTotalLog(BattleTotalLog totalLog)
{
#ifdef CENTERMATCH
	//WGS_CENTERBATTLELOG_LOCK;
	//CenterBattleLog cb;
	//CenterMatch cm_info;
	//sCenterMatchMgr.GetCenterMatch(totalLog.cb_id, &cm_info);



	//std::list<CenterBattleLog> logs;
	//GetCenterBattleLogList(&logs, "cb_id = %u and type = %u", totalLog.cm_id, enCenterBattleLogType_CenterMatchTotalInfo);

	//bool bFind = logs.size();
	//if (logs.size())
	//	cb = *logs.begin();

	//if (bFind)
	//{// 更新数据
	//	cb.data4++;							// 总轮数增加
	//	cb.data8 = time(0) - cb.data3;		// 游戏最终用时（每一把 结算）
	//}
	//else
	//{// 创建数据
	//	cb.cb_id = totalLog.cm_id;
	//	cb.gz_id = cm_info.gz_id;			// 分区ID
	//	cb.game_id = cm_info.game_id;		// 游戏ID
	//	cb.club_id = totalLog.jd_id;		// 俱乐部ID

	//	cb.src_pid = cm_info.pid;			// 房主PID

	//	cb.type = enCenterBattleLogType_CenterMatchTotalInfo;			// 一局日志

	//	cb.sdata1 = sXmlDataMgr.GetCenterBattleGameModeName(cm_info.reg_from, cm_info.game_id, cm_info.mode);	// 游戏名
	//	cb.sdata2 = cm_info.sdata2;			// 玩法
	//	cb.sdata3 = cm_info.battle_name;	// 比赛名称
	//	cb.sdata4 = cm_info.head;			// 房主头像
	//	cb.sdata7 = cm_info.join_code;		// 进入验证码

	//	cb.data1 = cm_info.base_coins;		// 底分
	//	cb.data2 = cm_info.fan_coins;		// 翻分
	//	cb.data3 = totalLog.use_time;		// 游戏创建时间
	//	cb.data4 = 1;						// 总局数
	//	cb.data5 = cm_info.limit_loop;		// 总局数
	//	cb.data8 = time(0) - cb.data3;		// 游戏最终用时

	//	cb.data11 = cm_info.sponsor_id;		// 赞助商id
	//	cb.data12 = cm_info.match_mode;			// 游戏玩法

	//	cb.create_time = totalLog.create_time;	// 创建时间
	//}

	//if (cm_info.cm_id)
	//{
	//	CenterMatchLogic *cmi = sCenterMatchMgr.FindMatchById(cm_info.cm_id);
	//	if (cmi)
	//	{

	//	}
	//}
#endif // CENTERMATCH

	return true;
}
